﻿using APS_Define_W32;
using APS168_W32;
using CommonTool;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Forms;
using Tool;

namespace Motions
{
    class APSMotion : Motions
    {
        public APSMotion(int nCardIndex, string strName, int nMinAxisNo, int nMaxAxisNo)
             : base(nCardIndex, strName, nMinAxisNo, nMaxAxisNo)
        {
            m_bEnable = false;
        }

        /// <summary>
        /// 轴卡初始化
        /// </summary>
        /// <returns></returns>
        public override void InitMotionCard()
        {
            Int32 rtn = 0;
            Int32 boardID_InBits = 0;
            rtn = APS168.APS_initial(ref boardID_InBits, 0);
            rtn = APS168.APS_load_param_from_file(AppDomain.CurrentDomain.BaseDirectory + "param.xml");
            if (0 != rtn)
            {
                m_bEnable = false;
                //MessageBox.Show(string.Format("运动控制卡GTS800初始化失败,卡号: {1}, result = {0}", rtn, m_nCardIndex));
                LogView.GetInstance().ShowLog( LogView.LogType.Error,string.Format("运动控制卡GTS800初始化失败,卡号: {1}, result = {0}", rtn, m_nCardIndex));
            }
            m_bEnable = true;
        }

        /// <summary>
        /// 关闭轴卡
        /// </summary>
        /// <returns></returns>
        public override void DeInitMotionCard()
        {
            Int32 rtn = 0;
            rtn = APS168.APS_close();

        }

        /// <summary>
        /// 按位获取输入信号
        /// </summary>
        /// <param name="nIndex">点位号</param>
        /// <returns></returns>
        public override bool ReadIn(int nCardN0, int nIndex)
        {
            int Data = 0;
            Int32 rtn = 0;
            rtn = APS168.APS_read_d_input(m_nCardIndex, 0, ref Data);
            // 卡号 组号 状态值 
            if (0 == (Data & (1 << (nIndex))))//卡号 4 通用输入
            {
                return false; //信号触发
            }
            return true;
        }

        /// <summary>
        /// 按位获取输出信号
        /// </summary>
        /// <param name="nIndex">点位号</param>
        /// <returns></returns>
        public override bool ReadOut(int nCardN0, int nIndex)
        {
            int Data = 0;
            Int32 rtn = 0;
            // 卡号 DO组号 数字输出通道号 返回值状态
            rtn = APS168.APS_read_d_channel_output(m_nCardIndex, 0, nIndex, ref Data);
            if (Data == 1)
            {
                return true;
            }
            return false;


        }

        /// <summary>
        /// 按位输出信号
        /// </summary>
        /// <param name="nIndex">点位号</param>
        /// <param name="bBit">True False</param>
        /// <returns></returns>
        public override void WriteOut(int nCardN0, int nIndex, bool bBit)
        {
            Int32 rtn = 0;
            int data = 2;
            if (bBit == true)
            {
                data = 1;
            }
            else
            {
                data = 0;
            }
            //写单个通道的DO输出
            //卡号 DO组号( DO 通道少于 32，则组号为 0) 数字输出通道号 D0状态值 0或1
            rtn = APS168.APS_write_d_channel_output(m_nCardIndex, 0, nIndex, data);
            if (0 != rtn)
            {
                MessageBox.Show(string.Format("第{0}张卡第{1}个输出信号失败原因{2} ---- ", m_nCardIndex, nIndex, rtn));
                LogView.GetInstance().ShowLog( LogView.LogType.Error,string.Format("第{0}张卡第{1}个输出信号失败原因{2}---- ", m_nCardIndex, nIndex, rtn));
            }

        }

        /// <summary>
        /// 开启使能
        /// </summary>
        /// <param name="nAxisNo">轴号</param>
        /// <returns></returns>
        public override void ServoOn(int nAxisNo)
        {
            Int32 rtn = 0;
            // 0 Off 1 On
            rtn = APS168.APS_set_servo_on(nAxisNo, 1);
            if (0 != rtn)
            {
                MessageBox.Show(string.Format("第{0}张卡第{1}个轴开始使能失败原因{2} ---- ", m_nCardIndex, nAxisNo, rtn));
                LogView.GetInstance().ShowLog(LogView.LogType.Error, string.Format("第{0}张卡第{1}个轴开始使能失败原因{2} ---- ", m_nCardIndex, nAxisNo, rtn));
            }
        }

        /// <summary>
        /// 关闭使能
        /// </summary>
        /// <param name="nAxisNo">轴号</param>
        /// <returns></returns>
        public override void ServoOff(int nAxisNo)
        {
            Int32 rtn = 0;
            // 0 Off 1 On
            rtn = APS168.APS_set_servo_on(nAxisNo, 0);
            if (0 != rtn)
            {
                MessageBox.Show(string.Format("第{0}张卡第{1}个轴开始使能失败原因{2} ---- ", m_nCardIndex, nAxisNo, rtn));
                LogView.GetInstance().ShowLog(LogView.LogType.Error, string.Format("第{0}张卡第{1}个轴开始使能失败原因{2} ---- ", m_nCardIndex, nAxisNo, rtn));
            }
        }

        /// <summary>
        /// 轴清除报警
        /// </summary>
        /// <param name="nAxisNo"></param>
        /// <returns></returns>
        public override void ClearAxisAlarm(int nAxisNo)
        {

        }

        /// <summary>
        /// 位置清零
        /// </summary>
        /// <param name="nAxisNo">轴号</param>
        /// <returns></returns>
        public override void SetPosZero(int nAxisNo)
        {
            Int32 rtn = 0;
            rtn = APS168.APS_set_position(nAxisNo, 0);

        }

        /// <summary>
        /// 轴正常停止
        /// </summary>
        /// <param name="nAxisNo">轴号</param>
        /// <returns></returns>
        public override void StopAxis(int nAxisNo)
        {
            Int32 rtn = 0;
            rtn = APS168.APS_stop_move(nAxisNo);
        }

        /// <summary>
        /// 轴紧急停止
        /// </summary>
        /// <param name="nAxisNo">轴号</param>
        /// <returns></returns>
        public override void EmgAxis(int nAxisNo)
        {
            Int32 rtn = 0;
            rtn = APS168.APS_emg_stop(nAxisNo);
        }

        /// <summary>
        /// 获取轴当前编码器位置
        /// </summary>
        /// <param name="nAxisNo">轴号</param>
        /// <returns></returns>
        public override double GetAxisActPos(int nAxisNo)
        {
            Int32 rtn = 0;
            int pos = 0;
            rtn = APS168.APS_get_position(nAxisNo, ref pos);
            if (0 == rtn)
            {
                return (long)pos ;
            }
            //MessageBox.Show(string.Format("第{0}张卡第{1}个轴获取编码器位置失败原因{2}---- ", m_nCardIndex, nAxisNo, rtn));
            LogView.GetInstance().ShowLog(LogView.LogType.Error, string.Format("第{0}张卡第{1}个轴获取编码器位置失败原因{2}---- ", m_nCardIndex, nAxisNo, rtn));
            return 0;
        }

        /// <summary>
        /// 获取轴当前规划位置
        /// </summary>
        /// <param name="nAxisNo"></param>
        /// <returns></returns>
        public override double GetAxisPrfPos(int nAxisNo)
        {
            Int32 rtn = 0;
            int pos = 0;
            rtn = APS168.APS_get_position(nAxisNo, ref pos);
            if (0 == rtn)
            {
                return (long)pos ;
            }
            //MessageBox.Show(string.Format("第{0}张卡第{1}个轴获取编码器位置失败原因{2}---- ", m_nCardIndex, nAxisNo, rtn));
            LogView.GetInstance().ShowLog(LogView.LogType.Error, string.Format("第{0}张卡第{1}个轴获取编码器位置失败原因{2}---- ", m_nCardIndex, nAxisNo, rtn));
            return 0;
        }

        /// <summary>
        /// 获取轴使能信号
        /// </summary>
        /// <param name="nAxisNo">轴号</param>
        /// <returns></returns>
        public override bool GetAxisSeverOn(int nAxisNo)
        {
            //0 ALM 伺服报警 1 ON 0 OFF 0x1
            //1 PEL 正硬限位            0x2
            //2 MEL 负硬限位            0x4
            //3 ORG 原点信号            0x8
            //4 EMG 急停信号            0x10
            //5 EZ  零相信号            0x20
            //6 INP 到位信号            0x40
            //7 SVON 伺服ON            0x80
            //8-10 Reserved 保留位     值为0       0x100 OX200 OX400
            //11 SPEL  软正限位              0x800
            //12 SMEL 软负限位       0x1000
            //13-15  Reserved 保留位 值为0       0x2000 0X4000 0X8000
            //其他为 保留

            int sts = 0;//轴状态字
            sts = APS168.APS_motion_io_status(nAxisNo);
            if (0 != (sts & 0x80))
            {
                //MessageBox.Show(string.Format("第{0}张卡第{1}个轴报警原因{2}---- ", m_nCardIndex, nAxisNo));
               // LogView.GetInstance().ShowLog( LogView.LogType.Error,string.Format("第{0}张卡第{1}个轴报警原因{2}---- ", m_nCardIndex, nAxisNo));
                return true;
            }
            return false;

        }

        /// <summary>
        /// 获取轴报警信号
        /// </summary>
        /// <param name="nAxisNo">轴号</param>
        /// <returns></returns>
        public override bool GetAxisAlarm(int nAxisNo)
        {
            //0 ALM 伺服报警 1 ON 0 OFF 0x1
            //1 PEL 正硬限位            0x2
            //2 MEL 负硬限位            0x4
            //3 ORG 原点信号            0x8
            //4 EMG 急停信号            0x10
            //5 EZ  零相信号            0x20
            //6 INP 到位信号            0x40
            //7 SVON 伺服ON            0x80
            //8-10 Reserved 保留位     值为0       0x100 OX200 OX400
            //11 SPEL  软正限位              0x800
            //12 SMEL 软负限位       0x1000
            //13-15  Reserved 保留位 值为0       0x2000 0X4000 0X8000
            //其他为 保留

            int sts = 0;//轴状态字
            sts = APS168.APS_motion_io_status(nAxisNo);
            if (0 != (sts & 0x1))
            {
                //MessageBox.Show(string.Format("第{0}张卡第{1}个轴报警原因{2}---- ", m_nCardIndex, nAxisNo));
                LogView.GetInstance().ShowLog( LogView.LogType.Error, string.Format("第{0}张卡第{1}个轴报警原因{2}---- ", m_nCardIndex, nAxisNo));
                return true;
            }
            return false;


        }

        /// <summary>
        /// 获取轴忙信号
        /// </summary>
        /// <param name="nAxisNo">轴号</param>
        /// <returns></returns>
        public override bool GetAxisBusy(int nAxisNo)
        {
            //0 CSTP 命令停止    0x1
            //1 VM 在最大速度    0x2
            //2 ACC 在加速       0x4
            //3 DEC 在减速       0x8
            //4 DIR 运动方向 1：正向运动 0：反向运动     0x10
            //5 MDN  运动完成 运动完成。 0：在运动， 1：运动完成（有可能是异常停止运动) 0x20
            //6 HMV 正在回零            0x40
            //7-9 Reserved 保留位 值为0            0x80 0x100 0x200
            //10 WAIT 轴处于等待状态     值为0       0x400
            //11 PTB  轴在进行点表缓冲运动              0x800
            //12-14 Reserved 软负限位       0x1000 0x2000
            //15  JOG 在进行寸动（JOG 运动） 值为0       0x4000 
            //16 HMV 正在回零            0x8000
            //17 Reserved 保留位 值为0            0x10000
            //18 WAIT 轴处于等待状态     值为0       0x100 OX200 OX400
            //19 PTB  轴在进行点表缓冲运动              0x800
            //20-27 Reserved 软负限位       0x1000
            //28  JOG 在进行寸动（JOG 运动） 值为0       0x2000 0X4000 0X8000
            //29-31 Reserved 软负限位       0x10000
            //其他为 保留

            int sts = 0;//轴状态字
            sts = APS168.APS_motion_status(nAxisNo);
            if (0 == (sts & 0x20))
            {
                //MessageBox.Show(string.Format("第{0}张卡第{1}个轴报警原因{2}---- ", m_nCardIndex, nAxisNo));
                LogView.GetInstance().ShowLog( LogView.LogType.Error,string.Format("第{0}张卡第{1}个轴报警原因{2}---- ", m_nCardIndex, nAxisNo));
                return true;
            }
            return false;
        }

        /// <summary>
        /// 获取轴到位完成信号
        /// </summary>
        /// <param name="nAxisNo">轴号</param>
        /// <returns></returns>
        public override bool GetAxisDone(int nAxisNo)
        {
            //0 CSTP 命令停止    0x1
            //1 VM 在最大速度    0x2
            //2 ACC 在加速       0x4
            //3 DEC 在减速       0x8
            //4 DIR 运动方向 1：正向运动 0：反向运动     0x10
            //5 MDN  运动完成 运动完成。 0：在运动， 1：运动完成（有可能是异常停止运动) 0x20
            //6 HMV 正在回零            0x40
            //7-9 Reserved 保留位 值为0            0x80 0x100 0x200
            //10 WAIT 轴处于等待状态     值为0       0x400
            //11 PTB  轴在进行点表缓冲运动              0x800
            //12-14 Reserved 软负限位       0x1000 0x2000
            //15  JOG 在进行寸动（JOG 运动） 值为0       0x4000 
            //16 HMV 正在回零            0x8000
            //17 Reserved 保留位 值为0            0x10000
            //18 WAIT 轴处于等待状态     值为0       0x100 OX200 OX400
            //19 PTB  轴在进行点表缓冲运动              0x800
            //20-27 Reserved 软负限位       0x1000
            //28  JOG 在进行寸动（JOG 运动） 值为0       0x2000 0X4000 0X8000
            //29-31 Reserved 软负限位       0x1000
            //其他为 保留



            int sts = 0;//轴状态字
            int sts1 = 0;//轴状态字
            sts = APS168.APS_motion_io_status(nAxisNo);//轴IO信号
            sts1 = APS168.APS_motion_status(nAxisNo);//轴运动状态

            // 有使能 正限位 负限位 到位 busy 
            if (0 != (sts & 0x80))//有使能
            {
                if (0 == (sts & 0x1))//无报警
                {
                    if (0 == (sts & 0x2)) //无正限位
                    {
                        if (0 == (sts & 0x4)) //无负限位
                        {
                            if (0 == (sts & 0x40))//到位信号
                            {
                                if (0 != (sts1 & 0X20))//不BUSY
                                {
                                    return true;
                                }
                            }


                        }
                    }
                }
            }
            return false;
        }

        /// <summary>
        /// 获取轴运动准备信号
        /// </summary>
        /// <param name="nAxisNo">轴号</param>
        /// <returns></returns>
        public override bool GetAxisReady(int nAxisNo)
        {
            //0 CSTP 命令停止    0x1
            //1 VM 在最大速度    0x2
            //2 ACC 在加速       0x4
            //3 DEC 在减速       0x8
            //4 DIR 运动方向 1：正向运动 0：反向运动     0x10
            //5 MDN  运动完成 运动完成。 0：在运动， 1：运动完成（有可能是异常停止运动) 0x20
            //6 HMV 正在回零            0x40
            //7-9 Reserved 保留位 值为0            0x80 0x100 0x200
            //10 WAIT 轴处于等待状态     值为0       0x400
            //11 PTB  轴在进行点表缓冲运动              0x800
            //12-14 Reserved 软负限位       0x1000 0x2000
            //15  JOG 在进行寸动（JOG 运动） 值为0       0x4000 
            //16 HMV 正在回零            0x8000
            //17 Reserved 保留位 值为0            0x10000
            //18 WAIT 轴处于等待状态     值为0       0x100 OX200 OX400
            //19 PTB  轴在进行点表缓冲运动              0x800
            //20-27 Reserved 软负限位       0x1000
            //28  JOG 在进行寸动（JOG 运动） 值为0       0x2000 0X4000 0X8000
            //29-31 Reserved 软负限位       0x1000
            //其他为 保留

            int sts = 0;//轴状态字
            sts = APS168.APS_motion_status(nAxisNo);
            if (0 == (sts & 0x400))
            {
                //MessageBox.Show(string.Format("第{0}张卡第{1}个轴报警原因{2}---- ", m_nCardIndex, nAxisNo));
                LogView.GetInstance().ShowLog( LogView.LogType.Error ,string.Format("第{0}张卡第{1}个轴报警原因{2}---- ", m_nCardIndex, nAxisNo));
                return true;
            }
            return false;

        }

        /// <summary>
        /// 获取轴原点信号
        /// </summary>
        /// <param name="nIndex">轴号</param>
        /// <returns></returns>
        public override bool GetAxisHome(int nAxisNo)
        {
            //0 ALM 伺服报警 1 ON 0 OFF 0x1  
            //1 PEL 正硬限位            0x2
            //2 MEL 负硬限位            0x4
            //3 ORG 原点信号            0x8
            //4 EMG 急停信号            0x10
            //5 EZ  零相信号            0x20
            //6 INP 到位信号            0x40
            //7 SVON 伺服ON            0x80
            //8-10 Reserved 保留位     值为0       0x100 OX200 OX400
            //11 SPEL  软正限位              0x800
            //12 SMEL 软负限位       0x1000
            //13-15  Reserved 保留位 值为0       0x2000 0X4000 0X8000
            //其他为 保留

            int sts = 0;//轴状态字
            sts = APS168.APS_motion_io_status(nAxisNo);
            if (0 != (sts & 0x8))
            {
                //MessageBox.Show(string.Format("第{0}张卡第{1}个轴报警原因{2}---- ", m_nCardIndex, nAxisNo));
                LogView.GetInstance().ShowLog(LogView.LogType.Error, string.Format("第{0}张卡第{1}个轴报警原因{2}---- ", m_nCardIndex, nAxisNo));
                return true;
            }
            return false;
        }

        /// <summary>
        /// 获取轴正限位信号
        /// </summary>
        /// <param name="nIndex">轴号</param>
        /// <returns></returns>
        public override bool GetPosLimit(int nAxisNo)
        {
            //0 ALM 伺服报警 1 ON 0 OFF 0x1
            //1 PEL 正硬限位            0x2
            //2 MEL 负硬限位            0x4
            //3 ORG 原点信号            0x8
            //4 EMG 急停信号            0x10
            //5 EZ  零相信号            0x20
            //6 INP 到位信号            0x40
            //7 SVON 伺服ON            0x80
            //8-10 Reserved 保留位     值为0       0x100 OX200 OX400
            //11 SPEL  软正限位              0x800
            //12 SMEL 软负限位       0x1000
            //13-15  Reserved 保留位 值为0       0x2000 0X4000 0X8000
            //其他为 保留

            int sts = 0;//轴状态字
            sts = APS168.APS_motion_io_status(nAxisNo);
            if (0 != (sts & 0x2))
            {
                //MessageBox.Show(string.Format("第{0}张卡第{1}个轴报警原因{2}---- ", m_nCardIndex, nAxisNo));
                LogView.GetInstance().ShowLog( LogView.LogType.Error ,string.Format("第{0}张卡第{1}个轴报警原因{2}---- ", m_nCardIndex, nAxisNo));
                return true;
            }
            return false;
        }

        /// <summary>
        /// 获取轴负限位信号
        /// </summary>
        /// <param name="nIndex">轴号</param>
        /// <returns></returns>
        public override bool GetNegLimit(int nAxisNo)
        {
            //0 ALM 伺服报警 1 ON 0 OFF 0x1
            //1 PEL 正硬限位            0x2
            //2 MEL 负硬限位            0x4
            //3 ORG 原点信号            0x8
            //4 EMG 急停信号            0x10
            //5 EZ  零相信号            0x20
            //6 INP 到位信号            0x40
            //7 SVON 伺服ON            0x80
            //8-10 Reserved 保留位     值为0       0x100 OX200 OX400
            //11 SPEL  软正限位              0x800
            //12 SMEL 软负限位       0x1000
            //13-15  Reserved 保留位 值为0       0x2000 0X4000 0X8000
            //其他为 保留

            int sts = 0;//轴状态字
            sts = APS168.APS_motion_io_status(nAxisNo);
            if (0 != (sts & 0x4))
            {
                //MessageBox.Show(string.Format("第{0}张卡第{1}个轴报警原因{2}---- ", m_nCardIndex, nAxisNo));
                LogView.GetInstance().ShowLog( LogView.LogType.Error,string.Format("第{0}张卡第{1}个轴报警原因{2}---- ", m_nCardIndex, nAxisNo));
                return true;
            }
            return false;

        }

        /// <summary>
        /// 绝对运动
        /// </summary>
        /// <param name="nAxisNo">轴号</param>
        /// <param name="nPos">目标位置</param>
        /// <param name="nSpeed">速度</param>
        /// <returns></returns>
        public override void AbsMove(int nAxisNo, double Pos, double Speed)
        {
            Int32 ret = 0;
            double nPOS = Pos;
            double nSpeed = Speed * SystemCfg.AxisCfg[nAxisNo].PluseRatio;
            ret += APS168.APS_set_axis_param_f(nAxisNo, (Int32)APS_Define.PRA_SF, 0.5);//S因素
            ret += APS168.APS_set_axis_param_f(nAxisNo, (Int32)APS_Define.PRA_ACC, 10000.0);//加速度
            ret += APS168.APS_set_axis_param_f(nAxisNo, (Int32)APS_Define.PRA_DEC, 10000.0);//减速带
            ret += APS168.APS_set_axis_param_f(nAxisNo, (Int32)APS_Define.PRA_VS, 1000.0);//启动速度
            ret += APS168.APS_set_axis_param_f(nAxisNo, (Int32)APS_Define.PRA_VM, 1000.0);//最大速度         
            ret += APS168.APS_absolute_move(nAxisNo, (int)nPOS, (int)nSpeed);
        }

        /// <summary>
        /// 相对运行
        /// </summary>
        /// <param name="nAxisNo">轴号</param>
        /// <param name="nPos">目标位置</param>
        /// <param name="nSpeed">速度</param>
        /// <returns></returns>
        public override void RelMove(int nAxisNo, double Pos, double Speed)
        {
            Int32 ret = 0;
            double nPOS = Pos;
            double nSpeed = Speed * SystemCfg.AxisCfg[nAxisNo].PluseRatio;
            ret += APS168.APS_set_axis_param_f(nAxisNo, (Int32)APS_Define.PRA_SF, 0.5);//S因素
            ret += APS168.APS_set_axis_param_f(nAxisNo, (Int32)APS_Define.PRA_ACC, 10000.0); // Set acceleration rate
            ret += APS168.APS_set_axis_param_f(nAxisNo, (Int32)APS_Define.PRA_DEC, 10000.0); // Set deceleration rate
            ret += APS168.APS_set_axis_param_f(nAxisNo, (Int32)APS_Define.PRA_VS, 1000.0);//启动速度
            ret += APS168.APS_set_axis_param_f(nAxisNo, (Int32)APS_Define.PRA_VM, 1000.0);//最大速度     
            ret += APS168.APS_relative_move(nAxisNo, (int)nPOS, (int)nSpeed);



        }

        /// <summary>
        /// Jog运动模式
        /// </summary>
        /// <param name="nAxisNo">轴号</param>
        /// <param name="nSpeed">速度</param>
        /// <param name="bPositive">方向</param>
        /// <returns></returns>
        public override void JogMove(int nAxisNo, double Speed, bool MovDir)
        {
            Int32 ret = 0;
            double nSpeed = Speed * SystemCfg.AxisCfg[nAxisNo].PluseRatio;
            int Postion = 0;
            if (MovDir == true)
            {
                Postion = 0;
            }
            else
            {
                Postion = 1;
            }

            ret+= APS168.APS_set_axis_param(nAxisNo, (int)APS_Define.PRA_JG_MODE, 1);//JOG模式 0连续 1步进
            ret += APS168.APS_set_axis_param(nAxisNo, (int)APS_Define.PRA_JG_DIR,Postion );//0负方向 1正方向
            ret += APS168.APS_set_axis_param_f(nAxisNo, (int)APS_Define.PRA_JG_ACC,10000.0 );//加速度
            ret += APS168.APS_set_axis_param_f(nAxisNo, (int)APS_Define.PRA_JG_DEC, 10000.0);//减速度
            ret += APS168.APS_set_axis_param_f(nAxisNo, (int)APS_Define.PRA_JG_VM, nSpeed);//最大速度
            ret += APS168.APS_jog_start(nAxisNo, 1);

        }

        /// <summary>
        /// 回原点
        /// </summary>
        /// <param name="nAxisNo">轴号</param>
        /// <param name="MoveDir">方向 0 是负方向 1是正方向</param>
        public override void HomeMove(int nAxisNo, int MoveDir, uint HomeMode)
        {
            Task.Factory.StartNew(() =>
            {
                Int32 ret = 0;
                double Speed = SystemCfg.AxisCfg[nAxisNo].OrgHSpeed * SystemCfg.AxisCfg[nAxisNo].PluseRatio;
                ret += APS168.APS_set_axis_param(nAxisNo, (Int32)APS_Define.PRA_HOME_MODE, 1); // Set home mode 回零模式  0 原点 1 征服限位  Mode0（ORG）  Mode1（PEL / MEL）
                ret += APS168.APS_set_axis_param(nAxisNo, (Int32)APS_Define.PRA_HOME_DIR, MoveDir); // Set home direction    0 正限位 1 负限位  Dir0（Positive） Dir1（Negative）
                ret += APS168.APS_set_axis_param_f(nAxisNo, (Int32)APS_Define.PRA_HOME_CURVE, 0); // Set acceleration paten (T-curve)
                ret += APS168.APS_set_axis_param_f(nAxisNo, (Int32)APS_Define.PRA_HOME_ACC, 1000000); // Set homing acceleration rate
                ret += APS168.APS_set_axis_param_f(nAxisNo, (Int32)APS_Define.PRA_HOME_VM, Speed); // Set homing maximum velocity.//速度
                ret += APS168.APS_set_axis_param_f(nAxisNo, (Int32)APS_Define.PRA_HOME_VO, 50000); // Set homing VO speed Homing 离开 ORG 信号的速率
                ret += APS168.APS_set_axis_param(nAxisNo, (Int32)APS_Define.PRA_HOME_EZA, 0); // Set EZ signal alignment (yes or no)
                ret += APS168.APS_set_axis_param_f(nAxisNo, (Int32)APS_Define.PRA_HOME_SHIFT, 0); // Set home position shfit distance. 
                ret += APS168.APS_set_axis_param_f(nAxisNo, (Int32)APS_Define.PRA_HOME_POS, 0); // Set final home position. position. Homing完成后位置命令设置
                Thread.Sleep(500); // Wait stable.
                ret += APS168.APS_home_move(nAxisNo);
            });

        }

        public override void InitExtIoCard(int CarsNO)
        {

        }

        public override void DeInitExtIoCard(int Card)
        {

        }

        public override bool ReadExtIn(int CardNo, int nIndex)
        {
            return false;
        }

        public override bool ReadExtOut(int CardNo, int nIndex)
        {
            return false;
        }

        public override void WriteExtOut(int CardNo, int nIndex, bool bBit)
        {

        }
       
        public override bool GetBusState()
        {
            throw new NotImplementedException();
        }

        public override void ClearBusAlarm()
        {
            throw new NotImplementedException();
        }

        public override bool HomeMove1(int nAxisNo, int MoveDir)
        {
            throw new NotImplementedException();
        }

        public override void OpenCmd(int cardNum, ushort channel, uint dir)
        {
            throw new NotImplementedException();
        }

        public override void CloseCmd(int cardNum, ushort channel)
        {
            throw new NotImplementedException();
        }

        public override void SetCmdData(int cardNum, ushort channel, double[] data)
        {
            throw new NotImplementedException();
        }

        public override int GetCmdFIFOCount(int cardNum, ushort channel)
        {
            throw new NotImplementedException();
        }

        public override void SetCmdDO(int cardNum, ushort channel)
        {
            throw new NotImplementedException();
        }

        public override void CloseCmdDO(int cardNum, ushort channel)
        {
            throw new NotImplementedException();
        }

        public override void ResetCmd(int cardNum, ushort channel)
        {
            throw new NotImplementedException();
        }

        public override bool HomeOK(int nAxisNo)
        {
            throw new NotImplementedException();
        }
    }
}

